package cn.iocoder.yudao.module.eval.service.template;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.eval.controller.admin.template.vo.EvalTemplatePageReqVO;
import cn.iocoder.yudao.module.eval.controller.admin.template.vo.EvalTemplateSaveReqVO;
import cn.iocoder.yudao.module.eval.dal.dataobject.template.EvalTemplateDO;
import cn.iocoder.yudao.module.eval.dal.mysql.template.EvalTemplateMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.eval.enums.ErrorCodeConstants.*;

/**
 * 评价模板 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
@Slf4j
public class EvalTemplateServiceImpl implements EvalTemplateService {

    @Resource
    private EvalTemplateMapper templateMapper;

    @Override
    public Long createTemplate(EvalTemplateSaveReqVO createReqVO) {
        // 校验模板编码唯一性
        validateTemplateCodeUnique(null, createReqVO.getTemplateCode());

        // 插入
        EvalTemplateDO template = BeanUtils.toBean(createReqVO, EvalTemplateDO.class);
        template.setUsageCount(0);
        template.setIsDefault(false);
        templateMapper.insert(template);
        // 返回
        return template.getId();
    }

    @Override
    public void updateTemplate(EvalTemplateSaveReqVO updateReqVO) {
        // 校验存在
        validateTemplateExists(updateReqVO.getId());
        // 校验模板编码唯一性
        validateTemplateCodeUnique(updateReqVO.getId(), updateReqVO.getTemplateCode());

        // 更新
        EvalTemplateDO updateObj = BeanUtils.toBean(updateReqVO, EvalTemplateDO.class);
        templateMapper.updateById(updateObj);
    }

    @Override
    public void deleteTemplate(Long id) {
        // 校验存在
        validateTemplateExists(id);
        // 删除
        templateMapper.deleteById(id);
    }

    private void validateTemplateExists(Long id) {
        if (templateMapper.selectById(id) == null) {
            throw exception(TEMPLATE_NOT_EXISTS);
        }
    }

    private void validateTemplateCodeUnique(Long id, String templateCode) {
        EvalTemplateDO template = templateMapper.selectByTemplateCode(templateCode);
        if (template == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的模板
        if (id == null) {
            throw exception(TEMPLATE_CODE_DUPLICATE);
        }
        if (!template.getId().equals(id)) {
            throw exception(TEMPLATE_CODE_DUPLICATE);
        }
    }

    @Override
    public EvalTemplateDO getTemplate(Long id) {
        return templateMapper.selectById(id);
    }

    @Override
    public List<EvalTemplateDO> getTemplateList(Collection<Long> ids) {
        return templateMapper.selectByIds(ids);
    }

    @Override
    public PageResult<EvalTemplateDO> getTemplatePage(EvalTemplatePageReqVO pageReqVO) {
        return templateMapper.selectPage(pageReqVO);
    }

    @Override
    public EvalTemplateDO getTemplateByCode(String templateCode) {
        return templateMapper.selectByTemplateCode(templateCode);
    }

    @Override
    public List<EvalTemplateDO> getTemplateListByMethodTypeId(Long methodTypeId) {
        return templateMapper.selectListByMethodTypeId(methodTypeId);
    }

    @Override
    public List<EvalTemplateDO> getTemplateListByProfessionAndType(String profession, Integer templateType) {
        return templateMapper.selectListByProfessionAndType(profession, templateType);
    }

    @Override
    public void publishTemplate(Long id) {
        // 校验存在
        validateTemplateExists(id);

        // 更新状态
        EvalTemplateDO updateObj = new EvalTemplateDO();
        updateObj.setId(id);
        updateObj.setTemplateStatus(1); // 已发布
        templateMapper.updateById(updateObj);
    }

    @Override
    public void disableTemplate(Long id) {
        // 校验存在
        validateTemplateExists(id);

        // 更新状态
        EvalTemplateDO updateObj = new EvalTemplateDO();
        updateObj.setId(id);
        updateObj.setTemplateStatus(2); // 已停用
        templateMapper.updateById(updateObj);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long copyTemplate(Long id, String newTemplateCode, String newTemplateName) {
        // 校验原模板存在
        validateTemplateExists(id);
        EvalTemplateDO originalTemplate = templateMapper.selectById(id);
        
        // 校验新模板编码唯一性
        validateTemplateCodeUnique(null, newTemplateCode);

        // 复制模板
        EvalTemplateDO newTemplate = BeanUtils.toBean(originalTemplate, EvalTemplateDO.class);
        newTemplate.setId(null);
        newTemplate.setTemplateCode(newTemplateCode);
        newTemplate.setTemplateName(newTemplateName);
        newTemplate.setTemplateStatus(0); // 设置为草稿状态
        newTemplate.setUsageCount(0);
        newTemplate.setIsDefault(false);
        templateMapper.insert(newTemplate);

        return newTemplate.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setDefaultTemplate(Long id, String profession, Integer templateType) {
        // 校验存在
        validateTemplateExists(id);

        // 先取消同职业同类型的其他默认模板
        List<EvalTemplateDO> existingDefaults = templateMapper.selectListByProfessionAndType(profession, templateType);
        for (EvalTemplateDO template : existingDefaults) {
            if (template.getIsDefault()) {
                EvalTemplateDO updateObj = new EvalTemplateDO();
                updateObj.setId(template.getId());
                updateObj.setIsDefault(false);
                templateMapper.updateById(updateObj);
            }
        }

        // 设置新的默认模板
        EvalTemplateDO updateObj = new EvalTemplateDO();
        updateObj.setId(id);
        updateObj.setIsDefault(true);
        templateMapper.updateById(updateObj);
    }

    @Override
    public List<EvalTemplateDO> getPublishedTemplateList() {
        return templateMapper.selectListByStatus(1); // 1表示已发布状态
    }

}
